package com.iwunu.gateway.util;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.ResourceUtils;

import com.iwunu.iot.common.util.DataUtil;

import javax.script.Invocable;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;
import java.io.*;
import java.util.Map;

/**
 * @author kinfeng
 * @date 2019/7/18 3:05 PM
 * @description 调用js文件中的加密协议
 */
@Configuration
public class JsXxetaUtil {
    private StringBuffer script = new StringBuffer();
    private Invocable inv ;
    @Value("${xxeat.js.path}")
    private String jsPath;


    @Bean
    public void init(){
        FileReader filereader = null ;
        BufferedReader bufferreader = null ;
        try {
        	File file = ResourceUtils.getFile(jsPath);
            filereader = new FileReader(file);
            bufferreader = new BufferedReader(filereader);
            String tempString = null;
            while ((tempString = bufferreader.readLine()) != null) {
                script.append(tempString).append("\n");
            }
            bufferreader.close();
            filereader.close();

            ScriptEngineManager mgr = new ScriptEngineManager();
            ScriptEngine engine = mgr.getEngineByName("javascript");
            engine.eval(script.toString());
            inv = (Invocable) engine;

        } catch (IOException e) {
            e.printStackTrace();
        }catch (ScriptException e) {
            e.printStackTrace();
        }
    }

    /**
     *  綁定鎖
     * @param basecode
     * @param mac
     * @return
     */
    public  String bindLock(String baseCode,String openId,String lockMode){
    	System.out.println("basecode, openId:"+baseCode+";"+openId+"lockMode:"+lockMode);
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("bindLock",new String[]{baseCode,openId,lockMode});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     *  解绑綁定鎖
     * @param basecode
     * @param mac
     * @return
     */
    public  String unbindLock(String baseCode,String openId){
    	System.out.println("basecode, openId:"+baseCode+";"+openId);
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("unbindLock",new String[]{baseCode,openId});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    } 
    
    /**
     * u1单个指令开锁
     * @param adminPwd
     * @param mac
     * @return
     */
    public  String getOpenLockData(Integer adminPwd, String mac){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("openLock",new String[]{adminPwd.toString(),mac});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }

	 /**
	  * 添加密码
	  * @param baseCode
	  * @param pwd
	  * @param startTime
	  * @param endTime
	  * @return
	  */
    public String addPwd(String baseCode,String pwd,Integer validCount){
    	  System.out.println("addPwd res:"+pwd.toString().toUpperCase());
    	 Object res = null ;
	    try {
	        res = (Object) inv.invokeFunction("addPwd",new String[]{baseCode,pwd,validCount.toString()});
	        System.out.println("addPwd res:"+res);
	    } catch (ScriptException e) {
	        e.printStackTrace();
	    } catch (NoSuchMethodException e) {
	        e.printStackTrace();
	    }
	    System.out.println("addPwd res:"+res.toString().toUpperCase());
	    return res.toString().toUpperCase();
    }
	 /**
	  * 添加密码
	  * @param baseCode
	  * @param pwd
	  * @param startTime
	  * @param endTime
	  * @return
	  */
   public String addTempPwd(String baseCode,String pwd,String startTime	,String endTime){
   	  System.out.println("addPwd res:"+pwd.toString().toUpperCase());
   	 Object res = null ;
	    try {
	        res = (Object) inv.invokeFunction("addTempPwd",new String[]{baseCode,pwd,startTime,endTime});
	        System.out.println("addTempPwd res:"+res);
	    } catch (ScriptException e) {
	        e.printStackTrace();
	    } catch (NoSuchMethodException e) {
	        e.printStackTrace();
	    }
	    System.out.println("addTempPwd res:"+res.toString().toUpperCase());
	    return res.toString().toUpperCase();
   }
	 /**
	  * 添加密码
	  * @param baseCode
	  * @param pwd
	  * @param startTime
	  * @param endTime
	  * @return
	  */
	 public String addTempPitNumPwd(String baseCode,String pitNum,String pwd,String startTime,String endTime){
	 	 Object res = null ;
		    try {
		        res = (Object) inv.invokeFunction("addTempPitNumPwd",new String[]{baseCode,pitNum,pwd,startTime,endTime});
		    } catch (ScriptException e) {
		        e.printStackTrace();
		    } catch (NoSuchMethodException e) {
		        e.printStackTrace();
		    }
		    return res.toString().toUpperCase();
	 }
    
	 /**
	  * 添卡模式
	  * @param pitNum
	  * @param startTime
	  * @param endTime
	  * @return
	  */
   public String addCard(Integer pitNum,String startTime,String endTime){
   	 Object res = null ;
	    try {
	        res = (Object) inv.invokeFunction("addNewPitNumCard",new String[]{pitNum.toString(),startTime,endTime});
	    } catch (ScriptException e) {
	        e.printStackTrace();
	    } catch (NoSuchMethodException e) {
	        e.printStackTrace();
	    }
	    return res.toString().toUpperCase();
   }
	 /**
	  *	 添指纹
	  * @param pitNum
	  * @param startTime
	  * @param endTime
	  * @return
	  */
	 public String addNewFingerprint(Integer pitNum,String startTime,String endTime){
	 	 Object res = null ;
		    try {
		        res = (Object) inv.invokeFunction("addNewFingerprint",new String[]{pitNum.toString(),startTime,endTime});
		    } catch (ScriptException e) {
		        e.printStackTrace();
		    } catch (NoSuchMethodException e) {
		        e.printStackTrace();
		    }
		    return res.toString().toUpperCase();
	 }
	   
	 /**
	  * 删除U/N锁密码
	  * @param baseCode
	  * @param pwd
	  * @param startTime
	  * @param endTime
	  * @return
	  */
   public String deletePwd(String baseCode,String pwd){
   	 Object res = null ;
	    try {
	        res = (Object) inv.invokeFunction("deletePwd",new String[]{baseCode,pwd});
	    } catch (ScriptException e) {
	        e.printStackTrace();
	    } catch (NoSuchMethodException e) {
	        e.printStackTrace();
	    }
	    return res.toString().toUpperCase();
   }
    
	 /**
		 * 删除非U/N锁密码
		* @param index
		* @return
		*/
		public String delPitNumPwd(Integer index){
		Object res = null ;
		try {
		    res = (Object) inv.invokeFunction("delPitNumPwd",new String[]{index.toString()});
		} catch (ScriptException e) {
		    e.printStackTrace();
		} catch (NoSuchMethodException e) {
		    e.printStackTrace();
		}
		return res.toString().toUpperCase();
		}
    /**
     * O,F,C设置管理员密码
     * @param mac
     * @param oldPwd
     * @param newPwd
     * @return
     */
    public String  setlockAdminPwd(String mac,String oldPwd,String newPwd) {
   	 Object res = null ;
	    try {
	        res = (Object) inv.invokeFunction("setlockAdminPwd",new String[]{mac,oldPwd,newPwd});
	    } catch (ScriptException e) {
	        e.printStackTrace();
	    } catch (NoSuchMethodException e) {
	        e.printStackTrace();
	    }
	    return res.toString().toUpperCase();
    }

	/**
	 *	 添加密码
	 * @param basecode
	 * @param index
	 * @param startTime
	 * @param endTime
	 * @param pwd
	 * @return
	 */
   public String addPitNumPwd(Integer basecode,Integer index,Integer pwd){
   	 Object res = null ;
	    try {
	        res = (Object) inv.invokeFunction("addPitNumPwd",new String[]{basecode.toString(),index.toString(),pwd.toString()});
	    } catch (ScriptException e) {
	        e.printStackTrace();
	    } catch (NoSuchMethodException e) {
	        e.printStackTrace();
	    }
	    return res.toString().toUpperCase();
   }

    /**
     * u1添加卡号
     * @param baseCode
     * @param cardNo
     * @param startTime
     * @param endTime
     * @return
     */
    public Map<String,String> addCardNo(String baseCode,String cardNo,String startTime,String endTime){
        if(!StringUtil.isNumber(cardNo)){
            cardNo = Long.valueOf(cardNo,16).toString();
        }
        StringBuffer buffer = new StringBuffer("AAAA1410");
        buffer.append(xxeta(baseCode,startTime,cardNo)).append(xxeta(baseCode,"1",endTime));
        return returnMap(buffer.toString().toUpperCase());
    }

    /**
     * u1删除卡号
     * @param baseCode
     * @param cardNo
     * @return
     */
    public String delCardNo(Integer baseCode,String cardNo){
    	Object res = null ;
    	try {
		    res = (Object) inv.invokeFunction("deleteCard",new String[]{baseCode.toString(),cardNo});
		} catch (ScriptException e) {
		    e.printStackTrace();
		} catch (NoSuchMethodException e) {
		    e.printStackTrace();
		}
		return res.toString().toUpperCase();
    }
    /**
     `* 非U/N删除卡号
     * @param index
     * @param cardNo
     * @return
     */
    public String deletePitNumCard(Integer index){
    	Object res = null ;
    	try {
		    res = (Object) inv.invokeFunction("deletePitNumCard",new String[]{index.toString()});
		} catch (ScriptException e) {
		    e.printStackTrace();
		} catch (NoSuchMethodException e) {
		    e.printStackTrace();
		}
		return res.toString().toUpperCase();
    }
    
    /**
    `* 删除指纹
    * @param index
    * @param cardNo
    * @return
    */
   public String delFinger(Integer index){
   	Object res = null ;
   	try {
		    res = (Object) inv.invokeFunction("deleteFingerprint",new String[]{index.toString()});
		} catch (ScriptException e) {
		    e.printStackTrace();
		} catch (NoSuchMethodException e) {
		    e.printStackTrace();
		}
		return res.toString().toUpperCase();
   } 
    
    /**
     * u1删除密码
     * @param baseCode
     * @param pwd
     * @return
     */
    public String delPwd(Integer baseCode,String pwd){
    	Object res = null ;
    	try {
		    res = (Object) inv.invokeFunction("deletePwd",new String[]{baseCode.toString(),pwd});
		} catch (ScriptException e) {
		    e.printStackTrace();
		} catch (NoSuchMethodException e) {
		    e.printStackTrace();
		}
		return res.toString().toUpperCase();
    }

    /**
     * 删除离线发的卡
     * @param baseCode
     * @param cardNo
     * @param endTime
     * @return
     */
    public Map<String,String> delOfflineCardNo(String baseCode, String cardNo, String endTime) {
        if(!StringUtil.isNumber(cardNo)){
            cardNo = Long.valueOf(cardNo,16).toString();
        }
        StringBuffer buffer = new StringBuffer("AAAA1C08");
        buffer.append(xxeta(baseCode,cardNo,endTime)).append(BluetoothDataUtil.makeChecksum(buffer.toString()));
        return returnMap(buffer.toString().toUpperCase());
    }

    /**
     * 恢复删除离线发的卡
     * @param baseCode
     * @param cardNo
     * @return
     */
    public Map<String,String> recoveryOfflineCardNo(String baseCode, String cardNo) {
        if(!StringUtil.isNumber(cardNo)){
            cardNo = Long.valueOf(cardNo,16).toString();
        }
        StringBuffer buffer = new StringBuffer("AAAA1E08");
        buffer.append(xxeta(baseCode,"0",cardNo)).append(BluetoothDataUtil.makeChecksum(buffer.toString()));
        return returnMap(buffer.toString().toUpperCase());
    }

    /***
     * 删除离线发的限时密码
     * @param baseCode
     * @param pwd
     * @return
     */
    public Map<String,String> delOfflineTimelimitedPwd(String baseCode, String pwd) {
        StringBuffer buffer = new StringBuffer("AAAA2008");
        buffer.append(xxeta(baseCode,"0",pwd)).append(BluetoothDataUtil.makeChecksum(buffer.toString()));
        return returnMap(buffer.toString().toUpperCase());
    }

    /**
     * 删除离线发的管理密码
     * @param baseCode
     * @param pwd
     * @return
     */
    public Map<String,String> delOfflineManagePwd(String baseCode, String pwd) {
        StringBuffer buffer = new StringBuffer("AAAA2208");
        buffer.append(xxeta(baseCode,"0",pwd)).append(BluetoothDataUtil.makeChecksum(buffer.toString()));
        return returnMap(buffer.toString().toUpperCase());
    }

    /**
     * 删除所有卡号
     * @param baseCode
     * @param time
     * @return
     */
    public Map<String,String> delAllCardNo(String baseCode, String time) {
        StringBuffer buffer = new StringBuffer("AAAA2408");
        buffer.append(xxeta(baseCode,"0",time)).append(BluetoothDataUtil.makeChecksum(buffer.toString()));
        return returnMap(buffer.toString().toUpperCase());
    }

    /**
     * 删除所有密码
     * @param baseCode
     * @param time
     * @return
     */
    public Map<String,String> delAllPwd(String baseCode, String time) {
        StringBuffer buffer = new StringBuffer("AAAA2608");
        buffer.append(xxeta(baseCode,"0",time)).append(BluetoothDataUtil.makeChecksum(buffer.toString()));
        return returnMap(buffer.toString().toUpperCase());
    }

    private String generateCmd(String cmdType, String baseCode,String pwd,String startTime,String endTime){
        StringBuffer buffer = new StringBuffer("AAAA").append(cmdType).append("10");
        buffer.append(xxeta(baseCode,startTime,pwd)).append(xxeta(baseCode,"1",endTime));
        return buffer.toString().toUpperCase();
    }
    
    public  String sendBasecodeAndN(String basecode){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("sendBasecodeAndN",new String[]{basecode});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }

    public  String sendAplusB(String basecode,String randomN,String subType){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("sendAplusB",new String[]{basecode,randomN,subType});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    public  String syscTime(String basecode){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("syncTimeData",new String[]{basecode});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    public  String syscTimeNew(String basecode){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("syncTimeDataNew",new String[]{basecode});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     * 查詢綁定狀態
     * @return
     */
    public  String selectBindLockStatus(){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("selectBindLockStatus",new String[]{});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    
    /**
     * 查詢綁定狀態
     * @return
     */
    public  String selectPower(){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("selectPower",new String[]{});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     * 设置NB是否可用
     * @return
     */
    public  String setNbFun(int key){
    	String keyStr = "0x0"+key;
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("setNbFun",new String[]{keyStr});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     * 读取开门记录条数
     */
    public  String readLockEventCount(){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("readLockEventCount",new String[]{});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     * 读取开门记录
     */
    public  String readLockEventAtIndex(Integer indexs){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("readLockEventAtIndex",new String[]{indexs.toString()});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     * 清除开门记录
     */
    public  String clearLockEvents(){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("clearLockEvents",new String[]{});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    /**
     * 读取Imei号
     * @return
     */
    public  String queryNbImei(){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("queryNbImei",new String[]{});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    } 
    /**
     * 	清除开门记录
	 *
     */
    public  String initCard(String busNum,String doorUnit,String doorFloor,String roomNum,String cardCluster){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("init",new String[]{busNum,doorUnit,doorFloor,roomNum,cardCluster});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString().toUpperCase();
    }
    
    public String xxeta(String key,String data1,String data2){
        Object res = null ;
        try {
            res = (Object) inv.invokeFunction("getEncodeDataStr",new String[]{key,data1,data2});
        } catch (ScriptException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
        return res.toString();
    }

    private Map<String,String> returnMap(String data){
        return DataUtil.generateMap("cmdData",data);
    }
    /**
     * 16求和
     * @param hexdata
     * @return
     */
    public  String makeChecksum(String hexdata) {
        if (hexdata == null || hexdata.equals("")) {
            return "00";
        }
        hexdata = hexdata.replaceAll(" ", "");
        int total = 0;
        int len = hexdata.length();
        if (len % 2 != 0) {
            return "00";
        }
        int num = 0;
        while (num < len) {
            String s = hexdata.substring(num, num + 2);
            total += Integer.parseInt(s, 16);
            num = num + 2;
        }
       String result = hexInt( total&0xff).substring(hexInt( total&0xff).length()-2,hexInt( total&0xff).length());
        return result ;
    }

    private static String hexInt(int total) {
        int a = total / 256;
        int b = total % 256;
        if (a > 255) {
            return hexInt(a) + format(b);
        }
        return format(a) + format(b);
    }
    private static String format(int hex) {
        String hexa = Integer.toHexString(hex);
        int len = hexa.length();
        if (len < 2) {
            hexa = "0" + hexa;
        }
        return hexa;
    }
    public static void main(String[] args) {
        									  
    }

}
